<template>
  <div class="tree-node" :style="{ 'padding-left': `${depth * indent}px` }">
    <!-- 节点内容 -->
    <div class="tree-node__content" :class="{
      'is-active': node.value === selectedValue,
      'has-children': hasChildren
    }" @click.stop="handleClick">
      <!-- 展开/折叠图标 -->
      <span v-if="hasChildren" class="tree-node__arrow" :class="{ 'is-expanded': isExpanded }"
        @click.stop="handleToggle">
        <slot name="arrow-icon" :expanded="isExpanded">
          {{ isExpanded ? '▼' : '▶' }}
        </slot>
      </span>
      <span v-else class="tree-node__placeholder"></span>

      <!-- 自定义图标插槽 -->
      <span class="tree-node__icon">
        <slot name="icon" :node="node">
          <span class="default-icon">
            {{ node.icon || (hasChildren ? '📁' : '📄') }}
          </span>
        </slot>
      </span>

      <!-- 节点标签 -->
      <span class="tree-node__label">{{ node.label }}</span>
    </div>

    <!-- 子节点 -->
    <div v-if="hasChildren && isExpanded" class="tree-node__children">
      <tree-node v-for="child in node.children" :key="child.value" :node="child" :depth="depth + 1"
        :selected-value="selectedValue" :expanded-keys="expandedKeys" @node-click="$emit('node-click', $event)"
        @toggle-expand="$emit('toggle-expand', $event)">
        <!-- 传递插槽 -->
        <template #icon="{ node }">
          <slot name="icon" :node="node" />
        </template>
        <template #arrow-icon="{ expanded }">
          <slot name="arrow-icon" :expanded="expanded" />
        </template>
      </tree-node>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType, computed } from 'vue'
import { TreeNode } from './TreeSelect.vue'

export default defineComponent({
  name: 'TreeNode',

  props: {
    node: {
      type: Object as PropType<TreeNode>,
      required: true
    },
    depth: {
      type: Number,
      default: 0
    },
    selectedValue: {
      type: [String, Number] as PropType<string | number>,
      default: null
    },
    expandedKeys: {
      type: Array as PropType<Array<string | number>>,
      default: () => []
    },
    indent: {
      type: Number,
      default: 20
    }
  },

  emits: ['node-click', 'toggle-expand'],

  setup(props, { emit }) {
    const hasChildren = computed(() => {
      return props.node.children && props.node.children.length > 0
    })

    const isExpanded = computed(() => {
      return props.expandedKeys.includes(props.node.value)
    })

    const handleClick = () => {
      emit('node-click', props.node)
    }

    const handleToggle = () => {
      emit('toggle-expand', props.node, !isExpanded.value)
    }

    return {
      hasChildren,
      isExpanded,
      handleClick,
      handleToggle
    }
  }
})
</script>

<style scoped>
.tree-node {
  margin-bottom: 2px;
}

.tree-node__content {
  padding: 6px 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.tree-node__content:hover {
  background-color: #f5f5f5;
}

.tree-node__content.is-active {
  background-color: #e0f0ff;
  color: #1890ff;
}

.tree-node__arrow,
.tree-node__placeholder {
  width: 16px;
  text-align: center;
  margin-right: 4px;
  font-size: 12px;
  transition: transform 0.2s;
}

.tree-node__arrow.is-expanded {
  transform: rotate(90deg);
}

.tree-node__arrow:hover {
  color: #1890ff;
}

.tree-node__icon {
  margin-right: 6px;
}

.tree-node__label {
  flex: 1;
}

.default-icon {
  display: inline-block;
  width: 20px;
  text-align: center;
}

.tree-node__children {
  transition: all 0.3s;
}

.has-children {
  margin-bottom: 2px;
}
</style>